// Have include guard.
#ifndef FPK_ACTIVATABLEFILTER_HPP
#define FPK_ACTIVATABLEFILTER_HPP

// Include files.
#include <boost/smart_ptr/shared_ptr.hpp>
#include "Internal/NullDeleter.hpp"
#include "Filter.hpp"

/**
 *  The ActivatableFilter template class that wraps another Filter and applies the inner Filter only if the ActivatableFilter is activated.
 *  
 *  @tparam Value The type of the input and output object.
 */
template<typename Value>
class ActivatableFilter :
	public Filter<Value>
{
	private:
		boost::shared_ptr<const Filter<Value> > m_filter;
		bool m_isActive;
	public:
		/**
		 *  Constructor for ActivatableFilter.
		 *  
		 *  @param filter A shared pointer to the filter to be wrapped.
		 */
		ActivatableFilter(boost::shared_ptr<const Filter<Value> > filter)
		{
			m_filter = filter;
			m_isActive = false;
		}
		
		/**
		 *  Constructor for ActivatableFilter.
		 *  
		 *  @param filter A pointer to the filter to be wrapped.
		 *  @param canDeleteFilter If the ActivatableFilter can delete the Filter so long as it functions correctly.
		 */
		ActivatableFilter(const Filter<Value> *filter, bool canDeleteFilter = false)
		{
			if (canDeleteFilter)
				m_filter = boost::shared_ptr<const Filter<Value> >(filter);
			else
				m_filter = boost::shared_ptr<const Filter<Value> >(filter, NullDeleter());
			
			m_isActive = false;
		}
		
		/**
		 *  Activate or deactivate the filter.
		 *  
		 *  @param isActive Whether to set the filter to be active.
		 */
		void SetIsActive(bool isActive)
		{
			m_isActive = isActive;
		}
		
		/**
		 *  Apply the filter to an input.
		 *  
		 *  If the filter is active, the inner filter will be applied.
		 *  If the filter is not active, a copy of the input will be output.
		 *  
		 *  @param input A reference to the input (which will not get modified).
		 *  @return The output of the filtered input.
		 */
		virtual Value Apply(const Value &input) const
		{
			if (m_isActive)
				return m_filter->Apply(input);
			else
				return input;
		}
};

#endif // #ifndef FPK_ACTIVATABLEFILTER_HPP
